//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// 
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Lesser General Public License for more details.
// 
// You should have received a copy of the GNU Lesser General Public License
// along with this program.  If not, see http://www.gnu.org/licenses/.
// 

#include <platdep/sockets.h>
#include <omnetpp.h>
#include <string>
#include "ExtAndroidClient.h"
#include "TelnetPkt_m.h"
#include "cSocketRTScheduler.h"

Define_Module(ExtAndroidClient);

ExtAndroidClient::ExtAndroidClient() {
    rtEvent = NULL;

}

ExtAndroidClient::~ExtAndroidClient() {
    cancelAndDelete(rtEvent);
}

void ExtAndroidClient::initialize()
{
    rtEvent = new cMessage("rtEvent");
    this->rtScheduler = check_and_cast<cSocketRTScheduler *>(simulation.getScheduler());
    //TODO:Is this needed still? Module assignment happens on connection
    c_socket = INVALID_SOCKET;

    addr = par("addr");
    srvAddr = par("srvAddr");

    rtScheduler->setInterfaceModule(this,rtEvent);
}

void ExtAndroidClient::handleMessage(cMessage *msg)
{
    if (msg==rtEvent)
        handleSocketEvent();
    else
        handleReply(check_and_cast<TelnetPkt *>(msg));
}

void ExtAndroidClient::handleSocketEvent()
{
    // get data from buffer
    std::string text = std::string(c_buffer, c_nTotalBytes);
    c_nTotalBytes = 0;

    // assemble and send Telnet packet
    TelnetPkt *telnetPkt = new TelnetPkt();
    telnetPkt->setPayload(text.c_str());
    telnetPkt->setName(text.c_str());
    telnetPkt->setDestAddress(srvAddr);
    telnetPkt->setSrcAddress(addr);

    send(telnetPkt,"g$o");
}

void ExtAndroidClient::handleReply(TelnetPkt *telnetReply)
{
    const char *reply = telnetReply->getPayload();
    rtScheduler->sendBytes(c_socket, reply, strlen(reply));
    delete telnetReply;
}

void ExtAndroidClient::setRtEvent(cMessage* rtEvent){
    this->rtEvent=rtEvent;
}

cMessage* ExtAndroidClient::getRtEvent(){
    return this->rtEvent;
}

/**
 * Socket
 */

void ExtAndroidClient::setSocket(SOCKET socketFd){
    this->c_socket=socketFd;
}

SOCKET ExtAndroidClient::getSocket(){
    return this->c_socket;
}

void ExtAndroidClient::closeSocket(){
    if(this->c_socket!=INVALID_SOCKET){
        close(this->c_socket);
        this->c_socket = INVALID_SOCKET;
    }
}

/**
 * Byte nums
 */

void    ExtAndroidClient::setTotalBytes(int n){
    this->c_nTotalBytes = n;
}

int     ExtAndroidClient::getTotalBytes(){
    return this->c_nTotalBytes;
}

void    ExtAndroidClient::setSentBytes(int n){
    this->c_nSentBytes=n;
}

void    ExtAndroidClient::incSentBytes(int n){
    int sum = this->c_nSentBytes+n;
    this->c_nSentBytes = sum;
}

int     ExtAndroidClient::getSentBytes(){
    return this->c_nSentBytes;
}

/**
 * Buffer
 */
void    ExtAndroidClient::setBuffer(char* buffer){
    strcpy(this->c_buffer, buffer);
}
void    ExtAndroidClient::getBuffer(char* buffer){
    strcpy(buffer, this->c_buffer);
}
char*   ExtAndroidClient::getBuffer(){
    return this->c_buffer;
}
void    ExtAndroidClient::zeroBuffer(){
    memset(this->c_buffer, '\0', sizeof(this->c_buffer));
}
